package cn.xinfei.xdecision.data.core.frame.check.impl;

import cn.xinfei.xdecision.common.model.datax.consts.VariableConst;
import cn.xinfei.xdecision.common.service.rpc.RequestContextConstant;
import cn.xinfei.xdecision.data.model.IVariableRequest;
import cn.xinfei.xdecision.data.core.context.ContextHolder;
import cn.xinfei.xdecision.data.core.frame.check.VarContextFactory;
import cn.xinfei.xdecision.data.core.util.XyfPreConditions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public abstract class BaseVarCheckService implements VarContextFactory {

    public void checkCreditChannel(IVariableRequest request) {
        Optional<JSONObject> inputParams = Optional.of(request).map(IVariableRequest::inputParams);
        inputParams.ifPresent(jsonObject -> XyfPreConditions.checkArgument(
                StringUtils.isNotBlank(jsonObject.getString(VariableConst.CREDIT_CHANNEL)),
                "征信查询必传参数 credit_channel 不能为空！"));

    }

    @Override
    public Map<String, String> initRpcContext() {
        Map<String, String> rpcContext = new HashMap<>();
        Map<String, Object> attributes = ContextHolder.getCurrentContext()
                .getAttributes().entrySet()
                .stream()
                .filter(entry -> !VariableConst.DEFAULT_EMPTY_STR.equals(entry.getValue()))
                .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
        rpcContext.put(VariableConst.RPC_CONTEXT, JSONObject.toJSONString(attributes));
        return rpcContext;
    }

    @Override
    public Map<String, String> initRpcContextFromInputParams(JSONObject inputParamJson) {
        Map<String, String> rpcContext = new ConcurrentHashMap<>();
        Map<String, Object> attributes = new ConcurrentHashMap<>();
        String traceId = MDC.get(VariableConst.TRACE_ID);
        traceId = StringUtils.isNotBlank(traceId) ? traceId : UUID.randomUUID().toString().replace("-", "");
        attributes.put(RequestContextConstant.APP, inputParamJson.getOrDefault(RequestContextConstant.APP, ""));
        attributes.put(RequestContextConstant.APP_NAME, inputParamJson.getOrDefault(RequestContextConstant.APP_NAME, ""));
        attributes.put(RequestContextConstant.APP_VERSION, inputParamJson.getOrDefault(RequestContextConstant.APP_VERSION, ""));
        attributes.put(RequestContextConstant.BIZ_FLOW_NUMBER, inputParamJson.getOrDefault(RequestContextConstant.BIZ_FLOW_NUMBER, ""));
        attributes.put(RequestContextConstant.BIZ_TYPE, inputParamJson.getOrDefault(RequestContextConstant.BIZ_TYPE, ""));
        attributes.put(RequestContextConstant.COLUMN_REQUESTER, RequestContextConstant.SYSTEM);
        attributes.put(RequestContextConstant.DEVICE_ID, inputParamJson.getOrDefault(RequestContextConstant.DEVICE_ID, ""));
        attributes.put(RequestContextConstant.ID_CARD_NUMBER, inputParamJson.getOrDefault(RequestContextConstant.ID_CARD_NUMBER, ""));
        attributes.put(RequestContextConstant.INNER_APP, inputParamJson.getOrDefault(RequestContextConstant.INNER_APP, ""));
        attributes.put(RequestContextConstant.MOBILE, inputParamJson.getOrDefault(RequestContextConstant.MOBILE, ""));
        attributes.put(RequestContextConstant.PRODUCT_TYPE, inputParamJson.getOrDefault(RequestContextConstant.PRODUCT_TYPE, ""));
        attributes.put(RequestContextConstant.REPORT_ID, inputParamJson.getOrDefault(RequestContextConstant.REPORT_ID, ""));
        attributes.put(RequestContextConstant.SEQ_ID, traceId);
        attributes.put(RequestContextConstant.SOURCE_TYPE, inputParamJson.getOrDefault(RequestContextConstant.SOURCE_TYPE, ""));
        attributes.put(RequestContextConstant.USER_ID, inputParamJson.getOrDefault(RequestContextConstant.USER_ID, ""));
        attributes = attributes.entrySet()
                .stream()
                .filter(entry -> !VariableConst.DEFAULT_EMPTY_STR.equals(entry.getValue()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        rpcContext.put(VariableConst.RPC_CONTEXT, JSONObject.toJSONString(attributes));
        return rpcContext;
    }


    @Override
    public Map<String, String> buildVarContext(JSONObject inputParams) {
        Map<String, String> rpcContextMap = initRpcContextFromInputParams(inputParams);
        String rpcContextStr = rpcContextMap.get(VariableConst.RPC_CONTEXT);
        Map<String, Object> varRpcContext = JSON.parseObject(rpcContextStr, Map.class);
        inputParams
                .fluentPut(RequestContextConstant.SEQ_ID,varRpcContext.getOrDefault(RequestContextConstant.SEQ_ID,
                        UUID.randomUUID().toString().trim().replaceAll("-", "")))
                .fluentPut(RequestContextConstant.COLUMN_REQUESTER,RequestContextConstant.SYSTEM)
                .fluentPut(RequestContextConstant.REQUESTER_SERVER,RequestContextConstant.SYSTEM_SERVER);

        return rpcContextMap;
    }
}
